import vnode from "./vnode";
import createElement from './createElement';
import updataChildren from './updataChildren';
/*
 * @Author: your name
 * @Date: 2021-10-04 12:47:43
 * @LastEditTime: 2021-10-05 19:50:56
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \diff\src\mysnabbdom\patch.js
 */

function samenode(node1,node2){
     return node1.key===node2.key && node2.sel === node1.sel
}

// 新旧dom内容对比
export default function(oldVnode,newVnode){
    //  1.判断 node1 是dom节点还是虚拟节点
    if(oldVnode.sel=='' || oldVnode.sel==undefined){
        // 如果传入的old节点为真实dom 需要将其包装为虚拟节点
        oldVnode = vnode(oldVnode.tagName.toLowerCase(),{},[],undefined,oldVnode);
    }
    // 2. 判断oldVnode和newnode是不是同一个节点(比较key是不是相同，元素名称是否相同)
    if(samenode(oldVnode,newVnode)){
        patchVnode(oldVnode,newVnode)

    }else{
        // 暴力删除  
        let nVnode = createElement(newVnode);
        // console.log(typeof oldVnode.elm)
        if(oldVnode.elm!==undefined && typeof nVnode == 'object'){
            oldVnode.elm.parentNode.insertBefore(nVnode,oldVnode.elm)
        }
    }
}

export function patchVnode(oldVnode,newVnode){
 
      let uni=0;   // 目的是精确插入
      const newch = newVnode.children;
      const oldch = oldVnode.children;
      const newEndIndex=newch.length;
      const oldEndIndex=oldch.length;
      // 判断新旧vnode是否是一个对象，按源地址比较
      if(oldVnode===newVnode) return
      // 判断新vnode有没有text
      if(newVnode.text!=undefined && (newVnode.children == undefined || newVnode.children.length==0)){
              if(oldVnode.text!=newVnode.text){
                  // 新旧节点text值不同
                  oldVnode.elm.innerHTML = newVnode.text; 
              }
      }else{
           if(oldVnode.children!=undefined && oldVnode.children.length!=0){
              //    老的新的都有children
              //    添加节点
              //    以下这种方法比较复杂 不是最优，使用diff的更新策略
              //    四种更新策略
              updataChildren(oldVnode,oldVnode.children,newVnode.children);
           }else{
              //    如果老的没有children 新的有chilren
              if(oldVnode.text){
                  // 清空老节点
                  oldVnode.elm.innerText=''; 
              }else if(oldVnode.children!=undefined && oldVnode.children.length!=0){
                  for(let i = 0;i<oldVnode.children.length;i++){
                      oldVnode.elm.removeChild(oldVnode.children[i].elm);
                  } 
              }
              // 将新节点添加到oldnode中去
              for(let i=0;i<newVnode.children.length;i++){
                  let dom = createElement(newVnode.children[i])
                  oldVnode.elm.appendChild(dom) 
               }    
           }
      }
}


function getkey(node){
       let { sel,data,children,text,elm } = node;
       const key = data.key
       return { sel,data,children,text,elm,key}
}

// 废弃
// for(let i = 0;i<newEndIndex;i++){
//     let nch = getkey(newch[i]);
//     let key=false;
//     for(let j = 0;j<oldEndIndex;j++){
//          let och = getkey(oldch[j]);
//          // 只要有一个相等的就不成立，就不会添加
//          if(nch.key==och.key){
//               key=true; 
//          }
//     }
//     if(!key){
//          let dom = createElement(newch[i]);
//          newch[i].elm=dom;
//          console.log(uni,i,newEndIndex-1)
//         if(i==newEndIndex-1){
//          oldVnode.elm.appendChild(dom)
//         }else{
//          // uni 作用就是 在添加之后
//          oldVnode.elm.insertBefore(dom,oldVnode.children[uni].elm); 
//         }
//     }else{
//        // 处理节点指针下移
//        // 旧节点那个位置等于新node的节点的时候才会+1，不等于不会加，避免oldVnode.children[uni].elm不存在问题
//        uni++;
//     }
// }